#ifndef __ADC_H
#define __ADC_H
/**
* @brief  选择单次触发、非扫描模式进行ADC初始化（对于是否进行中断与看门狗的配置，看函数内部注释）。该模式的优势在于读取前要先触发，而在触发时可以自行选择
					通道，实现多通道采集，无需担心数据被覆盖
  * @param  RCC_APB2Periph_ADC: 开启哪个ADC的时钟（详见RCC_APB2PeriphClockCmd函数）
	* @param  RCC_APB2Periph_GPIO: 开启哪个GPIO的时钟（同上）
	* @param  GPIOx:选择哪一片GPIO
	* @param  pin：一片GPIO中具体哪个引脚（参照结构体GPIO_InitTypeDef中的定义）
	* @param  RCC_PCLK2：对APB2的72MHz时钟，选择2、4、6、8分频。但因为STM32的ADC最大频率就是14MHz的，给更大的频率会导致稳定性下降，应该选6、8分频（详见
						RCC_ADCCLKConfig函数）
	* @param  ADCx：选用哪个ADC
	* @param  ADC_Mode：工作模式，分独立模式和各种双ADC模式（参考ADC_mode）
	* @param  ADC_DataAlign：对齐方式。STM32的ADC是12位的，而数据寄存器是16位的，因此需要选择数据是向左还是向右对齐。前者会使得数据变大16倍，需要再进
						行处理（参考ADC_data_align）
	* @param  ADC_ExternalTrigConv：外部触发转换选择，即选择硬件触发的触发控制的触发源（如果选用软件触发，这里就填ADC_ExternalTrigConv_None即可，参考
						ADC_external_trigger_sources_for_regular_channels_conversion）
  * @retval None
  */
void AD_Init_SingleTriggerMode(uint32_t RCC_APB2Periph_ADC, uint32_t RCC_APB2Periph_GPIO, GPIO_TypeDef* GPIOx, uint16_t pin, uint32_t RCC_PCLK2, 
	ADC_TypeDef* ADCx, uint32_t ADC_Mode, uint32_t ADC_DataAlign, uint32_t ADC_ExternalTrigConv);

/**
* @brief  单次触发模式下读取AD值
	* @param  ADCx：选用哪个ADC
	* @param  ADC_FLAG：需要读取的与ADC相关的标志位（参考寄存器ADC_SR的描述）
	* @param  ADC_Channel:指定ADC通道
	* @param  Rank：选择作为规则组的十六个序列中的哪一个（扫描模式下有效，否则就给个1，放在序列1即可）
	* @param  ADC_SampleTime：采样时间。时间越短，采样越快，越不稳定（以上四参数详见ADC_RegularChannelConfig函数）
  * @retval None
  */
uint16_t AD_GetValue_SingleTriggerMode(ADC_TypeDef* ADCx, uint8_t ADC_FLAG, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

/**
* @brief  选择连续转换、非扫描模式进行ADC初始化（默认为只开启一路ADC，如有需要增加路数，可使用ADC_AddChannel函数）（对于是否进行中断与看门狗的配置，看函数
					内部注释）连续转换模式的优点是不需要不断触发与等待转换完成，这些可以由硬件自行完成，CPU的压力小一点，如果只有一路ADC，可以使用这种模式，不断读取
					列表中同一位即可
  * @param  RCC_APB2Periph_ADC: 开启哪个ADC的时钟（详见RCC_APB2PeriphClockCmd函数）
	* @param  RCC_APB2Periph_GPIO: 开启哪个GPIO的时钟（同上）
	* @param  GPIOx:选择哪一片GPIO
	* @param  pin：一片GPIO中具体哪个引脚（参照结构体GPIO_InitTypeDef中的定义）
	* @param  RCC_PCLK2：对APB2的72MHz时钟，选择2、4、6、8分频。但因为STM32的ADC最大频率就是14MHz的，给更大的频率会导致稳定性下降，应该选6、8分频（详见
						RCC_ADCCLKConfig函数）
	* @param  ADCx：选用哪个ADC
	* @param  ADC_Channel:指定ADC通道
	* @param  Rank：选择作为规则组的十六个序列中的哪一个（扫描模式下有效，否则就给个1，放在序列1即可）
	* @param  ADC_SampleTime：采样时间。时间越短，采样越快，越不稳定（以上四参数详见ADC_RegularChannelConfig函数）
	* @param  ADC_Mode：工作模式，分独立模式和各种双ADC模式（参考ADC_mode）
	* @param  ADC_DataAlign：对齐方式。STM32的ADC是12位的，而数据寄存器是16位的，因此需要选择数据是向左还是向右对齐。前者会使得数据变大16倍，需要再进
						行处理（参考ADC_data_align）
	* @param  ADC_ExternalTrigConv：外部触发转换选择，即选择硬件触发的触发控制的触发源（如果选用软件触发，这里就填ADC_ExternalTrigConv_None即可，参考
						ADC_external_trigger_sources_for_regular_channels_conversion）
  * @retval None
  */
void AD_Init_ContinuousConvMode(uint32_t RCC_APB2Periph_ADC, uint32_t RCC_APB2Periph_GPIO, GPIO_TypeDef* GPIOx, uint16_t pin, uint32_t RCC_PCLK2, 
	ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime, uint32_t ADC_Mode, uint32_t ADC_DataAlign, uint32_t ADC_ExternalTrigConv);

/**
* @brief  读取AD值（该函数为单次转换模式下才需要用的）
	* @param  ADCx：选用哪个ADC
	* @param  ADC_FLAG：需要读取的与ADC相关的标志位（参考寄存器ADC_SR的描述）
  * @retval None
  */
uint16_t AD_GetValue_ContinuousConvMode(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);

/**
* @brief  选择连续转换模式进行ADC初始化，同时采用循环模式DMA进行数据转运（对于是否进行中断与看门狗的配置，看函数内部注释）连续转换模式的优点是不需要不断触
					发与等待转换完成，这些可以由硬件自行完成，CPU的压力小一点。看函数内部与其余地方隔开的代码的注释，按照需求添加或删除函数
  * @param  RCC_APB2Periph_ADC: 开启哪个ADC的时钟（详见RCC_APB2PeriphClockCmd函数）
	* @param  RCC_APB2Periph_GPIO: 开启哪个GPIO的时钟（同上）
	* @param  GPIOx:选择哪一片GPIO
	* @param  pin：一片GPIO中具体哪个（些）引脚（参照结构体GPIO_InitTypeDef中的定义，如有多个引脚需要初始化，可以将它们或起来，例如
						输入GPIO_Pin_0 | GPIO_Pin_1）
	* @param  RCC_PCLK2：对APB2的72MHz时钟，选择2、4、6、8分频。但因为STM32的ADC最大频率就是14MHz的，给更大的频率会导致稳定性下降，应该选6、8分频（详见
						RCC_ADCCLKConfig函数）
	* @param  ADCx：选用哪个ADC
	* @param  ADC_SampleTime：采样时间。时间越短，采样越快，越不稳定（以上四参数详见ADC_RegularChannelConfig函数）
	* @param  ADC_Mode：工作模式，分独立模式和各种双ADC模式（参考ADC_mode）
	* @param  ADC_DataAlign：对齐方式。STM32的ADC是12位的，而数据寄存器是16位的，因此需要选择数据是向左还是向右对齐。前者会使得数据变大16倍，需要再进
						行处理（参考ADC_data_align）
	* @param  ADC_NbrOfChannel：通道数量。只改这个是没用的，要在函数内部进行增减
	* @param  AD_Value：在主函数内定义的存放AD值的数组，记得传入强制类型转换为uint32_t的数组名
	* @param  DMAy_Channelx：DMA通道。ADC的硬件触发与DMA的通道是一一对应的，如ADC1对应DMA1的通道1，参考DMA1请求映像
  * @retval None
  */
void AD_Init_DMA(uint32_t RCC_APB2Periph_ADC, uint32_t RCC_APB2Periph_GPIO, GPIO_TypeDef* GPIOx, uint16_t pin, uint32_t RCC_PCLK2, ADC_TypeDef* ADCx, 
	uint8_t ADC_SampleTime, uint32_t ADC_Mode, uint32_t ADC_DataAlign, uint8_t ADC_NbrOfChannel, uint32_t AD_Value, DMA_Channel_TypeDef* DMAy_Channelx);
#endif
